import re

from ..util import trueReturn, falseReturn


def find_edges_nodes(file_path):
    """
    从 dot 文件中提取节点和边的数量，以及判断节点的数量。
    """
    node_count = 0
    edge_count = 0
    dec_count = 0

    try:
        with open(file_path, 'r', encoding='utf-8') as f:  # 指定编码为 utf-8
            print("utf-8")
            text = f.read()  # 读取整个文件内容
        # 匹配所有节点: 提取节点名称
        node_pattern = re.compile(r"^\s*([A-Z]+)\s*\[label=.*\];", re.MULTILINE)
        nodes = node_pattern.findall(text)
        node_count = len(nodes)
        print("nodes:", nodes)

        # 匹配所有边: 提取边的起点和终点
        edge_pattern = re.compile(r"^\s*([A-Z]+)\s*->\s*([A-Z]+)", re.MULTILINE)
        edges = edge_pattern.findall(text)
        edge_count = len(edges)
        print("edges:", edges)

        # 统计每个节点的出口数量
        node_exits = {}
        for start_node, _ in edges:
            if start_node in node_exits:
                node_exits[start_node] += 1
            else:
                node_exits[start_node] = 1

        # 判断节点：出口数量大于 1 的节点
        decision_nodes = [node for node, count in node_exits.items() if count > 1]
        dec_count = len(decision_nodes)
        print("decision_nodes:", decision_nodes)
    except UnicodeDecodeError:
        # 如果 UTF-8 解码失败，尝试使用 gbk
        with open(file_path, 'r', encoding='gbk', errors='ignore') as f:
            print("gbk")
            text = f.read()
        node_pattern = re.compile(r"^\s*([A-Z]+)\s*\[label=.*\];", re.MULTILINE)
        nodes = node_pattern.findall(text)
        node_count = len(nodes)
        print("nodes:", nodes)

        # 匹配所有边: 提取边的起点和终点
        edge_pattern = re.compile(r"^\s*([A-Z]+)\s*->\s*([A-Z]+)", re.MULTILINE)
        edges = edge_pattern.findall(text)
        edge_count = len(edges)
        print("edges:", edges)

        # 统计每个节点的出口数量
        node_exits = {}
        for start_node, _ in edges:
            if start_node in node_exits:
                node_exits[start_node] += 1
            else:
                node_exits[start_node] = 1

        # 判断节点：出口数量大于 1 的节点
        decision_nodes = [node for node, count in node_exits.items() if count > 1]
        dec_count = len(decision_nodes)
        print("decision_nodes:", decision_nodes)
    except Exception as e:  # 捕获其他异常
        print(f"Error in find_edges_nodes: {e}")
        return 0, 0, 0  # important to return 3 values
    return node_count, edge_count, dec_count


def getMcCabe(file_path):
    """
    计算 Dot 格式控制流图的 McCabe 复杂度，使用两种方法验证。
    """
    node_count, edge_count, dec_count = find_edges_nodes(file_path)

    # 圈复杂度计算方法 1：M = E - N + 2
    McCabe_2 = edge_count - node_count + 2

    # 圈复杂度计算方法 2：M = P + 1 (P 为判断节点数)
    McCabe_3 = dec_count + 1

    print(f"方法1计算的McCabe复杂度: {McCabe_2}")
    print(f"方法2计算的McCabe复杂度: {McCabe_3}")

    # 验证
    if McCabe_2 == McCabe_3:
        print('McCabe:', McCabe_2)
        return trueReturn(McCabe_2, 'ok')
    else:
        print('计算结果不一致，请检查!')
        return falseReturn(None, 'wrong input image!')


if __name__ == '__main__':
    file_path = r"C:\Users\33143\Desktop\cfg.dot"  # 替换为你的 .dot 文件路径
    result = getMcCabe(file_path)
    print(result)
